package dao;

import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import dto.RouteOrtDTO;
import dto.RouteOrtRegionDTO;

import om.Orte;
import om.Region;
import om.Route;

/**
 * Die Klasse Route. Alle Interaktionen mit der Datenbank
 * in Bezug auf die Entity Bean Route sollten in dieser Klasse behandelt werden.
 */
public class RouteDao extends HibernateDaoSupport {
	
	
    
	/**
	 * @return Eine Liste aller Orte die zu einer Region gehoeren
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<RouteOrtDTO> getRouteOrt(){
		HibernateTemplate template = getHibernateTemplate();
		return (List<RouteOrtDTO>) template.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(org.hibernate.Session session)
					throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(Route.class);
				List<Route> alleRouten = criteria.list();
				List<RouteOrtDTO> list = new LinkedList<RouteOrtDTO>();
				for (Route route : alleRouten) {
					RouteOrtDTO routeOrtDTO = new RouteOrtDTO(route, route.getFs_orteid());
					list.add(routeOrtDTO);
				}	
			return list;
			}	
		});
	}
	
	/**
	
	 * @return Eine Liste mit Routen, den dazugehoerigen Orten und den dazugehoerigen Regionen
	 */
	@SuppressWarnings({"unchecked", "rawtypes"})
	public List<RouteOrtRegionDTO> FindOrtBewertungRegionRoute(){
		HibernateTemplate template = getHibernateTemplate();
		return (List<RouteOrtRegionDTO>) template.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(org.hibernate.Session session)
					throws HibernateException, SQLException {
				Criteria criteria = session.createCriteria(Route.class);
				List<Route> alleRouten = criteria.list();
			
				List<RouteOrtRegionDTO> list = new LinkedList<RouteOrtRegionDTO>();
				for (Route route : alleRouten) {
					RouteOrtRegionDTO routeOrtRegionBewertungDTO = 
							new RouteOrtRegionDTO(route, route.getFs_orteid(), route.getFs_orteid().getFs_regionid());
					list.add(routeOrtRegionBewertungDTO);
			    }
				return list;
			}
			});
	}

	
	/**
	 
	 * @param id Es wird anhand der id der Datensatz des Ortes bestimmt {@link Orte}
	 * @return Eine Liste aller Routen die zu einem Ort gehoeren
	 */
	@SuppressWarnings("unchecked")
	public List<Route> findRouteByOrt(final Integer id){
		HibernateTemplate template = getHibernateTemplate();
		return (List<Route>) template.execute(new HibernateCallback<Object>() {
	
			@Override
			public Object doInHibernate(final org.hibernate.Session session)
					throws HibernateException, SQLException {
	
				final Orte ort = (Orte) session.load(Orte.class, id);
				final List<Route> list = (List<Route>) session.createCriteria(Route.class)
						.add(Restrictions.eq("fs_orteid", ort))
						.list();
				return list;
			}
		});
	}

	/**
	
	 <li> Speichert ein {@link Route}-Objekt
	 * @param route Objekt vom Typ Route
	 * @param ortid {@link Orte} Dazugehoeriger Ort zur Route
	  * @return Ein Objekt vom Typ Route
	 */
	public Route save(Route route, Integer ortid){
		HibernateTemplate template = getHibernateTemplate();
		Orte ort = template.get(Orte.class, ortid);
		route.setFs_orteid(ort);
		//Abfangen von leeren Feld in km-Strecke
		Route route1=route;
		
		if(route1.getStrecke()== null)
			route1.setStrecke(0.0f);
		
		if(route1.getName()=="")
			route1.setName("???");
			
		template.saveOrUpdate(route1);
		return route;
	}
	
	/**
	
	 * @param suche Eine vom User eingegebene Suche (wildcards)
	 * @return Alle Routen deren Namen die Wildcard-Suche beinhalten
	 */
	@SuppressWarnings("unchecked")
	public List<Route> findRouteBySearch(final String suche){
		final String suche1;
		suche1="%"+suche+"%";
		HibernateTemplate template = getHibernateTemplate();
		return (List<Route>) template.execute(new HibernateCallback<Object>() {
	   
			@Override
			public Object doInHibernate(final org.hibernate.Session session)
					throws HibernateException, SQLException {
	
				final List<Route> list = (List<Route>) session.createCriteria(Route.class)
						.add(Restrictions.ilike("name", suche1))
						.list();
				return list;
			}
		});
	}

	/**
	 <li>  Rueckgabewert ist eine einzelne Route anhand seines Primaerschluessels
	 * @param id Ist der Primaerschluessel {@link Route}
	 * @return Eine Objekt vom Typ Route
	 */
	public Route findById(Integer id) {
		HibernateTemplate template = getHibernateTemplate();
		return (Route) template.get(Route.class, id);
	}	
	
	/**
	 <li>  Rueckgabewert sind alle Routen aus der Datenbank
	 * @return eine Liste der Routen
	 * @see Route
	 */	
	@SuppressWarnings("unchecked")
	public List<Route> getAll(){
		HibernateTemplate template = getHibernateTemplate();
		@SuppressWarnings("rawtypes")
		List results = template.loadAll(Route.class);
		return results;
	}

	
	/**
	 <li>  Loescht ein bestimmtes {@link Route}-Objekt aus der Datenbank
	 * @param route Die {@link Route} die geloescht werden soll
	 */
	public void delete(Route route) {
		HibernateTemplate template = getHibernateTemplate();
        template.delete(route);
	}  
}
